Resumo:

Este artigo científico tem como objetivo apresentar uma análise detalhada da base de dados “Coronavírus Brasil”, uma fonte fundamental de informações sobre a pandemia da COVID-19 no Brasil. A base de dados é composta por uma ampla gama de informações epidemiológicas, incluindo casos confirmados, óbitos, datas de notificação, testes realizados e detalhes sobre a vacinação. Neste estudo, exploraremos a estrutura, o conteúdo e a relevância dessa base de dados para pesquisas científicas e análises de políticas públicas relacionadas à pandemia.

Funcionamento da Plataforma “Coronavírus Brasil”:

A plataforma “Coronavírus Brasil” é uma iniciativa governamental que coleta, armazena e disponibiliza informações sobre a pandemia da COVID-19 no país. Ela é mantida pelo Ministério da Saúde e pode ser acessada por pesquisadores, profissionais de saúde e o público em geral. Os dados são atualizados regularmente para refletir a evolução da pandemia.

Os dados relacionados à COVID-19 na plataforma “Coronavírus Brasil” são organizados em um formato tabular, que geralmente é representado em um arquivo CSV (Comma-Separated Values).

No contexto deste estudo, a escolha da linguagem de programação R para a análise da base de dados “Coronavírus Brasil” é altamente apropriada e vantajosa. O R é uma linguagem e ambiente de programação estatística amplamente reconhecido e utilizado por cientistas de dados, estatísticos e pesquisadores em todo o mundo. Várias razões tornam o R uma escolha valiosa para análises científicas, especialmente em epidemiologia e saúde pública.

Primeiramente, o R oferece um vasto ecossistema de pacotes e bibliotecas específicos para análise de dados e visualização, como o `dplyr` e o `ggplot2`, que simplificam o processo de manipulação e representação gráfica de dados. Essas ferramentas são particularmente úteis para lidar com dados tabulares, como os presentes na base “Coronavírus Brasil”.

A linguagem R também é conhecida por sua capacidade de produzir gráficos e visualizações de alta qualidade, essenciais para comunicar resultados e conclusões de forma clara e eficaz.

No contexto deste estudo sobre a pandemia da COVID-19, o R permitirá a importação, limpeza, análise e visualização de dados de maneira eficiente e rigorosa, contribuindo para a obtenção de insights valiosos e para a tomada de decisões informadas. Sua capacidade de realizar análises estatísticas avançadas, modelagem e mineração de dados também o torna uma escolha poderosa para explorar a complexidade dos dados epidemiológicos.

Análise de Sentimentos:

A análise de sentimentos é uma técnica que permite avaliar as emoções e opiniões expressas em textos. Pode ser aplicada para entender como o público percebe a pandemia. Coletando dados de redes sociais, fóruns ou notícias relacionadas à COVID-19, podemos analisar o sentimento geral do público em relação à pandemia, identificar tendências de preocupação ou otimismo e até mesmo detectar desinformação.

Extração de Informação:

A extração de informações envolve a identificação e captura de informações específicas em textos não estruturados. Na base “Coronavírus Brasil”, podemos aplicar essa técnica para extrair dados como números de casos, óbitos, datas de notificação e localizações geográficas dos relatórios, tornando as informações mais acessíveis e estruturadas para análise.

Agrupamento de Documentos:

Agrupamento de documentos é uma técnica que permite agrupar textos semelhantes em clusters. Isso pode ser útil para identificar padrões geográficos ou temporais na propagação da COVID-19. Ao agrupar relatórios por estado ou mês, podemos observar tendências regionais e sazonalidades nos dados.

Classificação de Texto:

A classificação de texto é usada para categorizar textos em classes predefinidas. Pode ser aplicada para identificar notícias ou relatórios de saúde pública que contenham informações imprecisas ou desatualizadas. Isso ajuda na detecção de informações errôneas que podem ser prejudiciais.

Descoberta de Associação:

A descoberta de associações busca encontrar padrões e relações ocultas entre itens em conjuntos de dados. Pode ser usada para identificar associações entre medidas de controle da pandemia, como lockdowns ou campanhas de vacinação, e a evolução dos casos de COVID-19 em diferentes estados.

Cancelamento de Esquemas:

O cancelamento de esquemas refere-se à identificação e eliminação de informações falsas ou desatualizadas na base de dados. Usando técnicas de mineração de texto, podemos verificar a veracidade de informações e marcar dados inconsistentes para posterior correção.

Coletando os de 2020 da Pandemia no Brasil e mostrando os casos que aconteceram no pais no ano de 2020

library(readxl)
library(dplyr)
library(ggplot2)

setwd("/Users/wisley/Documents/Matéria do 4 periodo /Minereção de Texto /Trabalho Final /Minerao-De-Texto--Covid-19")
# vamos coletar os dados 

# vamos manipular os dados agora 

dados_covid_2020_1_semestre <- read.csv2("HIST_PAINEL_COVIDBR_2020_Parte1_03out2023.csv")
# formatando as data do primeiro bimestre 
dados_covid_2020_1_semestre$data <- as.Date(dados_covid_2020_1_semestre$data, format = "%d/%m/%y")

# formatando as data do segundo bimestre 
dados_covid_2020_2_semestre <-read.csv2("HIST_PAINEL_COVIDBR_2020_Parte2_03out2023.csv")
dados_covid_2020_2_semestre$data <- as.Date(dados_covid_2020_2_semestre$data, format = "%Y-%m-%d")


# juntado os dois bimestre 
dados_covid_2020 <-bind_rows(dados_covid_2020_1_semestre,dados_covid_2020_2_semestre)

# colocando os dados que estão fazio como NA para facilitar a analise dos dados
dados_covid_2020$municipio[dados_covid_2020$municipio == ""] <- NA

dados_covid_2020$nomeRegiaoSaude[dados_covid_2020$nomeRegiaoSaude == ""] <- NA

dados_covid_2020$estado[dados_covid_2020$estado == ""] <- NA
#pegando os dados so do Brasil 
covid.Brasil <- filter(dados_covid_2020, is.na(municipio) & is.na(codmun) & is.na(estado))

Mostrando os dados dos estados do Brasil

# pegando os dados de todos os estados 
covid.estados <- filter(dados_covid_2020, is.na(municipio) & is.na(codmun) & !is.na(estado))

Analisando todos os estado separadamente

Estado do Acre

# Carregue as bibliotecas necessárias

library(dplyr)
library(ggplot2)
library(gridExtra)

Attaching package: ‘gridExtra’

The following object is masked from ‘package:dplyr’:

    combine
# Filtre os dados para o estado do Acre e renomeie as colunas
covid_ac_2020 <- covid.estados %>%
  filter(estado == "AC") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_ac_2020 <- covid_ac_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ac_resumo <- covid_ac_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_ac_resumo, casosNovos, "Casos Novos de COVID-19 no Acre por Mês", "Casos Novos")
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
Please use `linewidth` instead.
grafico_obitos <- criar_grafico(covid_ac_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Acre por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

NA
NA
NA

Estado do Alagoas



# Filtre os dados para o estado de Alagoas e renomeie as colunas
covid_al_2020 <- covid.estados %>%
  filter(estado == "AL") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_al_2020 <- covid_al_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_al_resumo <- covid_al_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_al_resumo, casosNovos, "Casos Novos de COVID-19 em Alagoas por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_al_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Alagoas por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Amazonas


# Filtre os dados para o estado do Amazonas e renomeie as colunas
covid_am_2020 <- covid.estados %>%
  filter(estado == "AM") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_am_2020 <- covid_am_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_am_resumo <- covid_am_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_am_resumo, casosNovos, "Casos Novos de COVID-19 no Amazonas por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_am_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Amazonas por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Amapá


# Filtre os dados para o estado do Amapá e renomeie as colunas
covid_ap_2020 <- covid.estados %>%
  filter(estado == "AP") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_ap_2020 <- covid_ap_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ap_resumo <- covid_ap_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_ap_resumo, casosNovos, "Casos Novos de COVID-19 no Amapá por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ap_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Amapá por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Bahia

#Bahia

# Filtre os dados para o estado da Bahia e renomeie as colunas
covid_ba_2020 <- covid.estados %>%
  filter(estado == "BA") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_ba_2020 <- covid_ba_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ba_resumo <- covid_ba_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_ba_resumo, casosNovos, "Casos Novos de COVID-19 na Bahia por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ba_resumo, obitosNovos, "Óbitos Novos de COVID-19 na Bahia por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Ceará



# Filtre os dados para o estado do Ceará e renomeie as colunas
covid_ce_2020 <- covid.estados %>%
  filter(estado == "CE") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_ce_2020 <- covid_ce_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ce_resumo <- covid_ce_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_ce_resumo, casosNovos, "Casos Novos de COVID-19 no Ceará por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ce_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Ceará por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Distrito Federal


# Filtre os dados para o Distrito Federal e renomeie as colunas
covid_df_2020 <- covid.estados %>%
  filter(estado == "DF") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_df_2020 <- covid_df_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_df_resumo <- covid_df_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_df_resumo, casosNovos, "Casos Novos de COVID-19 no Distrito Federal por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_df_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Distrito Federal por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Espírito Santo

#Espírito Santo
# Filtre os dados para o estado do Espírito Santo e renomeie as colunas
covid_es_2020 <- covid.estados %>%
  filter(estado == "ES") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_es_2020 <- covid_es_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_es_resumo <- covid_es_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_es_resumo, casosNovos, "Casos Novos de COVID-19 no Espírito Santo por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_es_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Espírito Santo por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Goiás

# Filtre os dados para o estado de Goiás e renomeie as colunas
covid_go_2020 <- covid.estados %>%
  filter(estado == "GO") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_go_2020 <- covid_go_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_go_resumo <- covid_go_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_go_resumo, casosNovos, "Casos Novos de COVID-19 em Goiás por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_go_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Goiás por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Maranhão

#Maranhão
# Filtre os dados para o estado do Maranhão e renomeie as colunas
covid_ma_2020 <- covid.estados %>%
  filter(estado == "MA") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_ma_2020 <- covid_ma_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ma_resumo <- covid_ma_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_ma_resumo, casosNovos, "Casos Novos de COVID-19 no Maranhão por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ma_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Maranhão por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Minas Gerais

#Minas Gerais
# Crie colunas para o ano e o mês
covid_ma_2020 <- covid_ma_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ma_resumo <- covid_ma_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_ma_resumo, casosNovos, "Casos Novos de COVID-19 no Maranhão por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ma_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Maranhão por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Mato Grosso do Sul

# Filtre os dados para o estado de Mato Grosso do Sul e renomeie as colunas
covid_ms_2020 <- covid.estados %>%
  filter(estado == "MS") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_ms_2020 <- covid_ms_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ms_resumo <- covid_ms_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_ms_resumo, casosNovos, "Casos Novos de COVID-19 em Mato Grosso do Sul por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ms_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Mato Grosso do Sul por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Mato Grosso

#Mato Grosso 
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado de Mato Grosso e renomeie as colunas
covid_mt_2020 <- covid.estados %>%
  filter(estado == "MT") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_mt_2020 <- covid_mt_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_mt_resumo <- covid_mt_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_mt_resumo, casosNovos, "Casos Novos de COVID-19 em Mato Grosso por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_mt_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Mato Grosso por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Pará

#Pará
# Filtre os dados para o estado do Pará e renomeie as colunas
covid_pa_2020 <- covid.estados %>%
  filter(estado == "PA") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_pa_2020 <- covid_pa_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_pa_resumo <- covid_pa_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_pa_resumo, casosNovos, "Casos Novos de COVID-19 no Pará por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_pa_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Pará por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

NA
NA

Estado do Paraíba

  

# Filtre os dados para o estado da Paraíba e renomeie as colunas
covid_pb_2020 <- covid.estados %>%
  filter(estado == "PB") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format = "%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_pb_2020 <- covid_pb_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_pb_resumo <- covid_pb_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_pb_resumo, casosNovos, "Casos Novos de COVID-19 na Paraíba por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_pb_resumo, obitosNovos, "Óbitos Novos de COVID-19 na Paraíba por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Pernambuco

# Pernambuco
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado de Pernambuco e renomeie as colunas
covid_pe_2020 <- covid.estados %>%
  filter(estado == "PE") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_pe_2020 <- covid_pe_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_pe_resumo <- covid_pe_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_pe_resumo, casosNovos, "Casos Novos de COVID-19 em Pernambuco por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_pe_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Pernambuco por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

NA
NA

Estado do Piauí

#Piauí 
# Filtre os dados para o estado do Piauí e renomeie as colunas
covid_pi_2020 <- covid.estados %>%
  filter(estado == "PI") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_pi_2020 <- covid_pi_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_pi_resumo <- covid_pi_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_pi_resumo, casosNovos, "Casos Novos de COVID-19 no Piauí por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_pi_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Piauí por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Paraná

#Paraná
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado do Paraná e renomeie as colunas
covid_pr_2020 <- covid.estados %>%
  filter(estado == "PR") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_pr_2020 <- covid_pr_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_pr_resumo <- covid_pr_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_pr_resumo, casosNovos, "Casos Novos de COVID-19 no Paraná por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_pr_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Paraná por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Rio de Janeiro

# Rio De Janeiro 
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado do Rio de Janeiro e renomeie as colunas
covid_rj_2020 <- covid.estados %>%
  filter(estado == "RJ") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_rj_2020 <- covid_rj_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_rj_resumo <- covid_rj_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_rj_resumo, casosNovos, "Casos Novos de COVID-19 no Rio de Janeiro por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_rj_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Rio de Janeiro por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

NA
NA

Estado do Rio Grande do Norte

#Rio Grande Do Norte
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado do Rio Grande do Norte e renomeie as colunas
covid_rn_2020 <- covid.estados %>%
  filter(estado == "RN") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_rn_2020 <- covid_rn_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_rn_resumo <- covid_rn_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_rn_resumo, casosNovos, "Casos Novos de COVID-19 no Rio Grande do Norte por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_rn_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Rio Grande do Norte por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Rondônia

# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado de Rondônia e renomeie as colunas
covid_ro_2020 <- covid.estados %>%
  filter(estado == "RO") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_ro_2020 <- covid_ro_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_ro_resumo <- covid_ro_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_ro_resumo, casosNovos, "Casos Novos de COVID-19 em Rondônia por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_ro_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Rondônia por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

NA
NA

Estado do Roraima

#Roriama
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado de Roraima e renomeie as colunas
covid_rr_2020 <- covid.estados %>%
  filter(estado == "RR") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_rr_2020 <- covid_rr_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_rr_resumo <- covid_rr_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_rr_resumo, casosNovos, "Casos Novos de COVID-19 em Roraima por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_rr_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Roraima por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Rio Grande do Sul

#Rio Grande Do Sul
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado do Rio Grande do Sul e renomeie as colunas
covid_rs_2020 <- covid.estados %>%
  filter(estado == "RS") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_rs_2020 <- covid_rs_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_rs_resumo <- covid_rs_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_rs_resumo, casosNovos, "Casos Novos de COVID-19 no Rio Grande do Sul por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_rs_resumo, obitosNovos, "Óbitos Novos de COVID-19 no Rio Grande do Sul por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Santa Catarina

#Santa Catarina
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado de Santa Catarina e renomeie as colunas
covid_sc_2020 <- covid.estados %>%
  filter(estado == "SC") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_sc_2020 <- covid_sc_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_sc_resumo <- covid_sc_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_sc_resumo, casosNovos, "Casos Novos de COVID-19 em Santa Catarina por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_sc_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Santa Catarina por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Sergipe

# Sergipe
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado de Sergipe e renomeie as colunas
covid_se_2020 <- covid.estados %>%
  filter(estado == "SE") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_se_2020 <- covid_se_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_se_resumo <- covid_se_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_se_resumo, casosNovos, "Casos Novos de COVID-19 em Sergipe por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_se_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Sergipe por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do São Paulo

# São Paulo 
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado de São Paulo e renomeie as colunas
covid_sp_2020 <- covid.estados %>%
  filter(estado == "SP") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_sp_2020 <- covid_sp_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_sp_resumo <- covid_sp_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_sp_resumo, casosNovos, "Casos Novos de COVID-19 em São Paulo por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_sp_resumo, obitosNovos, "Óbitos Novos de COVID-19 em São Paulo por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

Estado do Tocantins

#Tocantins
# Carregue as bibliotecas necessárias
library(dplyr)
library(ggplot2)
library(gridExtra)

# Filtre os dados para o estado de Tocantins e renomeie as colunas
covid_to_2020 <- covid.estados %>%
  filter(estado == "TO") %>%
  select(data, casosNovos, obitosNovos) %>%
  mutate(data = as.Date(data, format="%Y-%m-%d"))

# Crie colunas para o ano e o mês
covid_to_2020 <- covid_to_2020 %>%
  mutate(ano = lubridate::year(data),
         mes = lubridate::month(data))

# Agrupe por ano e mês e calcule os casos e óbitos novos
covid_to_resumo <- covid_to_2020 %>%
  group_by(ano, mes) %>%
  summarise(casosNovos = sum(casosNovos),
            obitosNovos = sum(obitosNovos), .groups = 'drop_last')

# Função para criar gráficos
criar_grafico <- function(data, y, titulo, ylab) {
  ggplot(data, aes(x = factor(mes), y = {{y}}, fill = factor(ano))) +
    geom_bar(stat = "identity", position = "dodge", color = "black", size = 0.5) +
    labs(title = titulo,
         x = "Mês",
         y = ylab) +
    theme_minimal()
}

# Crie gráficos
grafico_casos <- criar_grafico(covid_to_resumo, casosNovos, "Casos Novos de COVID-19 em Tocantins por Mês", "Casos Novos")
grafico_obitos <- criar_grafico(covid_to_resumo, obitosNovos, "Óbitos Novos de COVID-19 em Tocantins por Mês", "Óbitos Novos")

# Exiba ambos os gráficos lado a lado
grid.arrange(grafico_casos, grafico_obitos, ncol = 1)

LS0tCnRpdGxlOiAiVGVuZMOqbmNpYXMgRXBpZGVtaW9sw7NnaWNhcyBkYSBDT1ZJRC0xOSBubyBCcmFzaWw6IEltcGFjdG8gZGEgVmFjaW5hw6fDo28gbm9zIENhc29zIGUgw5NiaXRvcyBwb3IgRXN0YWRvIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIyMgUmVzdW1vOgoKRXN0ZSBhcnRpZ28gY2llbnTDrWZpY28gdGVtIGNvbW8gb2JqZXRpdm8gYXByZXNlbnRhciB1bWEgYW7DoWxpc2UgZGV0YWxoYWRhIGRhIGJhc2UgZGUgZGFkb3MgIkNvcm9uYXbDrXJ1cyBCcmFzaWwiLCB1bWEgZm9udGUgZnVuZGFtZW50YWwgZGUgaW5mb3JtYcOnw7VlcyBzb2JyZSBhIHBhbmRlbWlhIGRhIENPVklELTE5IG5vIEJyYXNpbC4gQSBiYXNlIGRlIGRhZG9zIMOpIGNvbXBvc3RhIHBvciB1bWEgYW1wbGEgZ2FtYSBkZSBpbmZvcm1hw6fDtWVzIGVwaWRlbWlvbMOzZ2ljYXMsIGluY2x1aW5kbyBjYXNvcyBjb25maXJtYWRvcywgw7NiaXRvcywgZGF0YXMgZGUgbm90aWZpY2HDp8OjbywgdGVzdGVzIHJlYWxpemFkb3MgZSBkZXRhbGhlcyBzb2JyZSBhIHZhY2luYcOnw6NvLiBOZXN0ZSBlc3R1ZG8sIGV4cGxvcmFyZW1vcyBhIGVzdHJ1dHVyYSwgbyBjb250ZcO6ZG8gZSBhIHJlbGV2w6JuY2lhIGRlc3NhIGJhc2UgZGUgZGFkb3MgcGFyYSBwZXNxdWlzYXMgY2llbnTDrWZpY2FzIGUgYW7DoWxpc2VzIGRlIHBvbMOtdGljYXMgcMO6YmxpY2FzIHJlbGFjaW9uYWRhcyDDoCBwYW5kZW1pYS4KCioqRnVuY2lvbmFtZW50byBkYSBQbGF0YWZvcm1hICJDb3JvbmF2w61ydXMgQnJhc2lsIjoqKgoKQSBwbGF0YWZvcm1hICJDb3JvbmF2w61ydXMgQnJhc2lsIiDDqSB1bWEgaW5pY2lhdGl2YSBnb3Zlcm5hbWVudGFsIHF1ZSBjb2xldGEsIGFybWF6ZW5hIGUgZGlzcG9uaWJpbGl6YSBpbmZvcm1hw6fDtWVzIHNvYnJlIGEgcGFuZGVtaWEgZGEgQ09WSUQtMTkgbm8gcGHDrXMuIEVsYSDDqSBtYW50aWRhIHBlbG8gTWluaXN0w6lyaW8gZGEgU2HDumRlIGUgcG9kZSBzZXIgYWNlc3NhZGEgcG9yIHBlc3F1aXNhZG9yZXMsIHByb2Zpc3Npb25haXMgZGUgc2HDumRlIGUgbyBww7pibGljbyBlbSBnZXJhbC4gT3MgZGFkb3Mgc8OjbyBhdHVhbGl6YWRvcyByZWd1bGFybWVudGUgcGFyYSByZWZsZXRpciBhIGV2b2x1w6fDo28gZGEgcGFuZGVtaWEuCgpPcyBkYWRvcyByZWxhY2lvbmFkb3Mgw6AgQ09WSUQtMTkgbmEgcGxhdGFmb3JtYSAiQ29yb25hdsOtcnVzIEJyYXNpbCIgc8OjbyBvcmdhbml6YWRvcyBlbSB1bSBmb3JtYXRvIHRhYnVsYXIsIHF1ZSBnZXJhbG1lbnRlIMOpIHJlcHJlc2VudGFkbyBlbSB1bSBhcnF1aXZvIENTViAoQ29tbWEtU2VwYXJhdGVkIFZhbHVlcykuCgpObyBjb250ZXh0byBkZXN0ZSBlc3R1ZG8sIGEgZXNjb2xoYSBkYSBsaW5ndWFnZW0gZGUgcHJvZ3JhbWHDp8OjbyBSIHBhcmEgYSBhbsOhbGlzZSBkYSBiYXNlIGRlIGRhZG9zICJDb3JvbmF2w61ydXMgQnJhc2lsIiDDqSBhbHRhbWVudGUgYXByb3ByaWFkYSBlIHZhbnRham9zYS4gTyBSIMOpIHVtYSBsaW5ndWFnZW0gZSBhbWJpZW50ZSBkZSBwcm9ncmFtYcOnw6NvIGVzdGF0w61zdGljYSBhbXBsYW1lbnRlIHJlY29uaGVjaWRvIGUgdXRpbGl6YWRvIHBvciBjaWVudGlzdGFzIGRlIGRhZG9zLCBlc3RhdMOtc3RpY29zIGUgcGVzcXVpc2Fkb3JlcyBlbSB0b2RvIG8gbXVuZG8uIFbDoXJpYXMgcmF6w7VlcyB0b3JuYW0gbyBSIHVtYSBlc2NvbGhhIHZhbGlvc2EgcGFyYSBhbsOhbGlzZXMgY2llbnTDrWZpY2FzLCBlc3BlY2lhbG1lbnRlIGVtIGVwaWRlbWlvbG9naWEgZSBzYcO6ZGUgcMO6YmxpY2EuCgpQcmltZWlyYW1lbnRlLCBvIFIgb2ZlcmVjZSB1bSB2YXN0byBlY29zc2lzdGVtYSBkZSBwYWNvdGVzIGUgYmlibGlvdGVjYXMgZXNwZWPDrWZpY29zIHBhcmEgYW7DoWxpc2UgZGUgZGFkb3MgZSB2aXN1YWxpemHDp8OjbywgY29tbyBvIFxgZHBseXJcYCBlIG8gXGBnZ3Bsb3QyXGAsIHF1ZSBzaW1wbGlmaWNhbSBvIHByb2Nlc3NvIGRlIG1hbmlwdWxhw6fDo28gZSByZXByZXNlbnRhw6fDo28gZ3LDoWZpY2EgZGUgZGFkb3MuIEVzc2FzIGZlcnJhbWVudGFzIHPDo28gcGFydGljdWxhcm1lbnRlIMO6dGVpcyBwYXJhIGxpZGFyIGNvbSBkYWRvcyB0YWJ1bGFyZXMsIGNvbW8gb3MgcHJlc2VudGVzIG5hIGJhc2UgIkNvcm9uYXbDrXJ1cyBCcmFzaWwiLgoKQSBsaW5ndWFnZW0gUiB0YW1iw6ltIMOpIGNvbmhlY2lkYSBwb3Igc3VhIGNhcGFjaWRhZGUgZGUgcHJvZHV6aXIgZ3LDoWZpY29zIGUgdmlzdWFsaXphw6fDtWVzIGRlIGFsdGEgcXVhbGlkYWRlLCBlc3NlbmNpYWlzIHBhcmEgY29tdW5pY2FyIHJlc3VsdGFkb3MgZSBjb25jbHVzw7VlcyBkZSBmb3JtYSBjbGFyYSBlIGVmaWNhei4KCk5vIGNvbnRleHRvIGRlc3RlIGVzdHVkbyBzb2JyZSBhIHBhbmRlbWlhIGRhIENPVklELTE5LCBvIFIgcGVybWl0aXLDoSBhIGltcG9ydGHDp8OjbywgbGltcGV6YSwgYW7DoWxpc2UgZSB2aXN1YWxpemHDp8OjbyBkZSBkYWRvcyBkZSBtYW5laXJhIGVmaWNpZW50ZSBlIHJpZ29yb3NhLCBjb250cmlidWluZG8gcGFyYSBhIG9idGVuw6fDo28gZGUgaW5zaWdodHMgdmFsaW9zb3MgZSBwYXJhIGEgdG9tYWRhIGRlIGRlY2lzw7VlcyBpbmZvcm1hZGFzLiBTdWEgY2FwYWNpZGFkZSBkZSByZWFsaXphciBhbsOhbGlzZXMgZXN0YXTDrXN0aWNhcyBhdmFuw6dhZGFzLCBtb2RlbGFnZW0gZSBtaW5lcmHDp8OjbyBkZSBkYWRvcyB0YW1iw6ltIG8gdG9ybmEgdW1hIGVzY29saGEgcG9kZXJvc2EgcGFyYSBleHBsb3JhciBhIGNvbXBsZXhpZGFkZSBkb3MgZGFkb3MgZXBpZGVtaW9sw7NnaWNvcy4KCioqQW7DoWxpc2UgZGUgU2VudGltZW50b3M6KioKCkEgYW7DoWxpc2UgZGUgc2VudGltZW50b3Mgw6kgdW1hIHTDqWNuaWNhIHF1ZSBwZXJtaXRlIGF2YWxpYXIgYXMgZW1vw6fDtWVzIGUgb3BpbmnDtWVzIGV4cHJlc3NhcyBlbSB0ZXh0b3MuIFBvZGUgc2VyIGFwbGljYWRhIHBhcmEgZW50ZW5kZXIgY29tbyBvIHDDumJsaWNvIHBlcmNlYmUgYSBwYW5kZW1pYS4gQ29sZXRhbmRvIGRhZG9zIGRlIHJlZGVzIHNvY2lhaXMsIGbDs3J1bnMgb3Ugbm90w61jaWFzIHJlbGFjaW9uYWRhcyDDoCBDT1ZJRC0xOSwgcG9kZW1vcyBhbmFsaXNhciBvIHNlbnRpbWVudG8gZ2VyYWwgZG8gcMO6YmxpY28gZW0gcmVsYcOnw6NvIMOgIHBhbmRlbWlhLCBpZGVudGlmaWNhciB0ZW5kw6puY2lhcyBkZSBwcmVvY3VwYcOnw6NvIG91IG90aW1pc21vIGUgYXTDqSBtZXNtbyBkZXRlY3RhciBkZXNpbmZvcm1hw6fDo28uCgoqKkV4dHJhw6fDo28gZGUgSW5mb3JtYcOnw6NvOioqCgpBIGV4dHJhw6fDo28gZGUgaW5mb3JtYcOnw7VlcyBlbnZvbHZlIGEgaWRlbnRpZmljYcOnw6NvIGUgY2FwdHVyYSBkZSBpbmZvcm1hw6fDtWVzIGVzcGVjw61maWNhcyBlbSB0ZXh0b3MgbsOjbyBlc3RydXR1cmFkb3MuIE5hIGJhc2UgIkNvcm9uYXbDrXJ1cyBCcmFzaWwiLCBwb2RlbW9zIGFwbGljYXIgZXNzYSB0w6ljbmljYSBwYXJhIGV4dHJhaXIgZGFkb3MgY29tbyBuw7ptZXJvcyBkZSBjYXNvcywgw7NiaXRvcywgZGF0YXMgZGUgbm90aWZpY2HDp8OjbyBlIGxvY2FsaXphw6fDtWVzIGdlb2dyw6FmaWNhcyBkb3MgcmVsYXTDs3Jpb3MsIHRvcm5hbmRvIGFzIGluZm9ybWHDp8O1ZXMgbWFpcyBhY2Vzc8OtdmVpcyBlIGVzdHJ1dHVyYWRhcyBwYXJhIGFuw6FsaXNlLgoKKipBZ3J1cGFtZW50byBkZSBEb2N1bWVudG9zOioqCgpBZ3J1cGFtZW50byBkZSBkb2N1bWVudG9zIMOpIHVtYSB0w6ljbmljYSBxdWUgcGVybWl0ZSBhZ3J1cGFyIHRleHRvcyBzZW1lbGhhbnRlcyBlbSBjbHVzdGVycy4gSXNzbyBwb2RlIHNlciDDunRpbCBwYXJhIGlkZW50aWZpY2FyIHBhZHLDtWVzIGdlb2dyw6FmaWNvcyBvdSB0ZW1wb3JhaXMgbmEgcHJvcGFnYcOnw6NvIGRhIENPVklELTE5LiBBbyBhZ3J1cGFyIHJlbGF0w7NyaW9zIHBvciBlc3RhZG8gb3UgbcOqcywgcG9kZW1vcyBvYnNlcnZhciB0ZW5kw6puY2lhcyByZWdpb25haXMgZSBzYXpvbmFsaWRhZGVzIG5vcyBkYWRvcy4KCioqQ2xhc3NpZmljYcOnw6NvIGRlIFRleHRvOioqCgpBIGNsYXNzaWZpY2HDp8OjbyBkZSB0ZXh0byDDqSB1c2FkYSBwYXJhIGNhdGVnb3JpemFyIHRleHRvcyBlbSBjbGFzc2VzIHByZWRlZmluaWRhcy4gUG9kZSBzZXIgYXBsaWNhZGEgcGFyYSBpZGVudGlmaWNhciBub3TDrWNpYXMgb3UgcmVsYXTDs3Jpb3MgZGUgc2HDumRlIHDDumJsaWNhIHF1ZSBjb250ZW5oYW0gaW5mb3JtYcOnw7VlcyBpbXByZWNpc2FzIG91IGRlc2F0dWFsaXphZGFzLiBJc3NvIGFqdWRhIG5hIGRldGVjw6fDo28gZGUgaW5mb3JtYcOnw7VlcyBlcnLDtG5lYXMgcXVlIHBvZGVtIHNlciBwcmVqdWRpY2lhaXMuCgoqKkRlc2NvYmVydGEgZGUgQXNzb2NpYcOnw6NvOioqCgpBIGRlc2NvYmVydGEgZGUgYXNzb2NpYcOnw7VlcyBidXNjYSBlbmNvbnRyYXIgcGFkcsO1ZXMgZSByZWxhw6fDtWVzIG9jdWx0YXMgZW50cmUgaXRlbnMgZW0gY29uanVudG9zIGRlIGRhZG9zLiBQb2RlIHNlciB1c2FkYSBwYXJhIGlkZW50aWZpY2FyIGFzc29jaWHDp8O1ZXMgZW50cmUgbWVkaWRhcyBkZSBjb250cm9sZSBkYSBwYW5kZW1pYSwgY29tbyBsb2NrZG93bnMgb3UgY2FtcGFuaGFzIGRlIHZhY2luYcOnw6NvLCBlIGEgZXZvbHXDp8OjbyBkb3MgY2Fzb3MgZGUgQ09WSUQtMTkgZW0gZGlmZXJlbnRlcyBlc3RhZG9zLgoKKipDYW5jZWxhbWVudG8gZGUgRXNxdWVtYXM6KioKCk8gY2FuY2VsYW1lbnRvIGRlIGVzcXVlbWFzIHJlZmVyZS1zZSDDoCBpZGVudGlmaWNhw6fDo28gZSBlbGltaW5hw6fDo28gZGUgaW5mb3JtYcOnw7VlcyBmYWxzYXMgb3UgZGVzYXR1YWxpemFkYXMgbmEgYmFzZSBkZSBkYWRvcy4gVXNhbmRvIHTDqWNuaWNhcyBkZSBtaW5lcmHDp8OjbyBkZSB0ZXh0bywgcG9kZW1vcyB2ZXJpZmljYXIgYSB2ZXJhY2lkYWRlIGRlIGluZm9ybWHDp8O1ZXMgZSBtYXJjYXIgZGFkb3MgaW5jb25zaXN0ZW50ZXMgcGFyYSBwb3N0ZXJpb3IgY29ycmXDp8Ojby4KCkNvbGV0YW5kbyBvcyBkZSAyMDIwIGRhIFBhbmRlbWlhIG5vIEJyYXNpbCBlIG1vc3RyYW5kbyBvcyBjYXNvcyBxdWUgYWNvbnRlY2VyYW0gbm8gcGFpcyBubyBhbm8gZGUgMjAyMAoKYGBge3J9CmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCgojc2V0YW5kbyBvIG5vc3NvIHJlcG9zaXRvcmlvIApzZXR3ZCgiL1VzZXJzL3dpc2xleS9Eb2N1bWVudHMvTWF0ZcyBcmlhIGRvIDQgcGVyaW9kbyAvTWluZXJlY8ynYcyDbyBkZSBUZXh0byAvVHJhYmFsaG8gRmluYWwgL01pbmVyYW8tRGUtVGV4dG8tLUNvdmlkLTE5IikKIyB2YW1vcyBjb2xldGFyIG9zIGRhZG9zIAoKIyB2YW1vcyBtYW5pcHVsYXIgb3MgZGFkb3MgYWdvcmEgCgpkYWRvc19jb3ZpZF8yMDIwXzFfc2VtZXN0cmUgPC0gcmVhZC5jc3YyKCJISVNUX1BBSU5FTF9DT1ZJREJSXzIwMjBfUGFydGUxXzAzb3V0MjAyMy5jc3YiKQojIGZvcm1hdGFuZG8gYXMgZGF0YSBkbyBwcmltZWlybyBiaW1lc3RyZSAKZGFkb3NfY292aWRfMjAyMF8xX3NlbWVzdHJlJGRhdGEgPC0gYXMuRGF0ZShkYWRvc19jb3ZpZF8yMDIwXzFfc2VtZXN0cmUkZGF0YSwgZm9ybWF0ID0gIiVkLyVtLyV5IikKCiMgZm9ybWF0YW5kbyBhcyBkYXRhIGRvIHNlZ3VuZG8gYmltZXN0cmUgCmRhZG9zX2NvdmlkXzIwMjBfMl9zZW1lc3RyZSA8LXJlYWQuY3N2MigiSElTVF9QQUlORUxfQ09WSURCUl8yMDIwX1BhcnRlMl8wM291dDIwMjMuY3N2IikKZGFkb3NfY292aWRfMjAyMF8yX3NlbWVzdHJlJGRhdGEgPC0gYXMuRGF0ZShkYWRvc19jb3ZpZF8yMDIwXzJfc2VtZXN0cmUkZGF0YSwgZm9ybWF0ID0gIiVZLSVtLSVkIikKCgojIGp1bnRhZG8gb3MgZG9pcyBiaW1lc3RyZSAKZGFkb3NfY292aWRfMjAyMCA8LWJpbmRfcm93cyhkYWRvc19jb3ZpZF8yMDIwXzFfc2VtZXN0cmUsZGFkb3NfY292aWRfMjAyMF8yX3NlbWVzdHJlKQoKIyBjb2xvY2FuZG8gb3MgZGFkb3MgcXVlIGVzdMOjbyBmYXppbyBjb21vIE5BIHBhcmEgZmFjaWxpdGFyIGEgYW5hbGlzZSBkb3MgZGFkb3MKZGFkb3NfY292aWRfMjAyMCRtdW5pY2lwaW9bZGFkb3NfY292aWRfMjAyMCRtdW5pY2lwaW8gPT0gIiJdIDwtIE5BCgpkYWRvc19jb3ZpZF8yMDIwJG5vbWVSZWdpYW9TYXVkZVtkYWRvc19jb3ZpZF8yMDIwJG5vbWVSZWdpYW9TYXVkZSA9PSAiIl0gPC0gTkEKCmRhZG9zX2NvdmlkXzIwMjAkZXN0YWRvW2RhZG9zX2NvdmlkXzIwMjAkZXN0YWRvID09ICIiXSA8LSBOQQojcGVnYW5kbyBvcyBkYWRvcyBzbyBkbyBCcmFzaWwgCmNvdmlkLkJyYXNpbCA8LSBmaWx0ZXIoZGFkb3NfY292aWRfMjAyMCwgaXMubmEobXVuaWNpcGlvKSAmIGlzLm5hKGNvZG11bikgJiBpcy5uYShlc3RhZG8pKQoKCmBgYAoKTW9zdHJhbmRvIG9zIGRhZG9zIGRvcyBlc3RhZG9zIGRvIEJyYXNpbAoKYGBge3J9CiMgcGVnYW5kbyBvcyBkYWRvcyBkZSB0b2RvcyBvcyBlc3RhZG9zIApjb3ZpZC5lc3RhZG9zIDwtIGZpbHRlcihkYWRvc19jb3ZpZF8yMDIwLCBpcy5uYShtdW5pY2lwaW8pICYgaXMubmEoY29kbXVuKSAmICFpcy5uYShlc3RhZG8pKQpgYGAKCkFuYWxpc2FuZG8gdG9kb3Mgb3MgZXN0YWRvIHNlcGFyYWRhbWVudGUKCkVzdGFkbyBkbyBBY3JlCgpgYGB7cn0KIyBDYXJyZWd1ZSBhcyBiaWJsaW90ZWNhcyBuZWNlc3PDoXJpYXMKCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZG8gQWNyZSBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfYWNfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIkFDIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9hY18yMDIwIDwtIGNvdmlkX2FjXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfYWNfcmVzdW1vIDwtIGNvdmlkX2FjXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfYWNfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gQWNyZSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfYWNfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gQWNyZSBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgoKCmBgYApFc3RhZG8gZG8gQWxhZ29hcwpgYGB7cn0KCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIEFsYWdvYXMgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX2FsXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJBTCIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfYWxfMjAyMCA8LSBjb3ZpZF9hbF8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX2FsX3Jlc3VtbyA8LSBjb3ZpZF9hbF8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2FsX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IGVtIEFsYWdvYXMgcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2FsX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IGVtIEFsYWdvYXMgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gQW1hem9uYXMKYGBge3J9CgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRvIEFtYXpvbmFzIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9hbV8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiQU0iKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX2FtXzIwMjAgPC0gY292aWRfYW1fMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9hbV9yZXN1bW8gPC0gY292aWRfYW1fMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9hbV9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBBbWF6b25hcyBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfYW1fcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gQW1hem9uYXMgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gQW1hcMOhCmBgYHtyfQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBBbWFww6EgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX2FwXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJBUCIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfYXBfMjAyMCA8LSBjb3ZpZF9hcF8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX2FwX3Jlc3VtbyA8LSBjb3ZpZF9hcF8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2FwX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5vIEFtYXDDoSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfYXBfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gQW1hcMOhIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIEJhaGlhCmBgYHtyfQojQmFoaWEKCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZGEgQmFoaWEgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX2JhXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJCQSIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfYmFfMjAyMCA8LSBjb3ZpZF9iYV8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX2JhX3Jlc3VtbyA8LSBjb3ZpZF9iYV8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2JhX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5hIEJhaGlhIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9iYV9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBuYSBCYWhpYSBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgpgYGAKCkVzdGFkbyBkbyBDZWFyw6EKYGBge3J9CgoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBDZWFyw6EgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX2NlXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJDRSIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfY2VfMjAyMCA8LSBjb3ZpZF9jZV8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX2NlX3Jlc3VtbyA8LSBjb3ZpZF9jZV8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2NlX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5vIENlYXLDoSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfY2VfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gQ2VhcsOhIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIERpc3RyaXRvIEZlZGVyYWwKCmBgYHtyfQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIERpc3RyaXRvIEZlZGVyYWwgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX2RmXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJERiIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfZGZfMjAyMCA8LSBjb3ZpZF9kZl8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX2RmX3Jlc3VtbyA8LSBjb3ZpZF9kZl8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2RmX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5vIERpc3RyaXRvIEZlZGVyYWwgcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2RmX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IG5vIERpc3RyaXRvIEZlZGVyYWwgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gRXNww61yaXRvIFNhbnRvCmBgYHtyfQojRXNww61yaXRvIFNhbnRvCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZG8gRXNww61yaXRvIFNhbnRvIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9lc18yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiRVMiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX2VzXzIwMjAgPC0gY292aWRfZXNfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9lc19yZXN1bW8gPC0gY292aWRfZXNfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9lc19yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBFc3DDrXJpdG8gU2FudG8gcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2VzX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IG5vIEVzcMOtcml0byBTYW50byBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCmBgYAoKRXN0YWRvIGRvIEdvacOhcwoKYGBge3J9CiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZGUgR29pw6FzIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9nb18yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiR08iKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX2dvXzIwMjAgPC0gY292aWRfZ29fMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9nb19yZXN1bW8gPC0gY292aWRfZ29fMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9nb19yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBHb2nDoXMgcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX2dvX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IGVtIEdvacOhcyBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCmBgYAoKRXN0YWRvIGRvIE1hcmFuaMOjbwoKYGBge3J9CiNNYXJhbmjDo28KIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBNYXJhbmjDo28gZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX21hXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJNQSIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfbWFfMjAyMCA8LSBjb3ZpZF9tYV8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX21hX3Jlc3VtbyA8LSBjb3ZpZF9tYV8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX21hX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5vIE1hcmFuaMOjbyBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfbWFfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gTWFyYW5ow6NvIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKYGBgCgpFc3RhZG8gZG8gTWluYXMgR2VyYWlzCgoKYGBge3J9CiNNaW5hcyBHZXJhaXMKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9tYV8yMDIwIDwtIGNvdmlkX21hXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfbWFfcmVzdW1vIDwtIGNvdmlkX21hXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfbWFfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gTWFyYW5ow6NvIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9tYV9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBNYXJhbmjDo28gcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQpgYGAKCkVzdGFkbyBkbyBNYXRvIEdyb3NzbyBkbyBTdWwKCmBgYHtyfQojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIE1hdG8gR3Jvc3NvIGRvIFN1bCBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfbXNfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIk1TIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9tc18yMDIwIDwtIGNvdmlkX21zXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfbXNfcmVzdW1vIDwtIGNvdmlkX21zXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfbXNfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gTWF0byBHcm9zc28gZG8gU3VsIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9tc19yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBNYXRvIEdyb3NzbyBkbyBTdWwgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gTWF0byBHcm9zc28KCmBgYHtyfQojTWF0byBHcm9zc28gCiMgQ2FycmVndWUgYXMgYmlibGlvdGVjYXMgbmVjZXNzw6FyaWFzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIE1hdG8gR3Jvc3NvIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9tdF8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiTVQiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX210XzIwMjAgPC0gY292aWRfbXRfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9tdF9yZXN1bW8gPC0gY292aWRfbXRfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9tdF9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBNYXRvIEdyb3NzbyBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfbXRfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gTWF0byBHcm9zc28gcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gUGFyw6EKCgpgYGB7cn0KI1BhcsOhCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZG8gUGFyw6EgZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX3BhXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJQQSIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfcGFfMjAyMCA8LSBjb3ZpZF9wYV8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX3BhX3Jlc3VtbyA8LSBjb3ZpZF9wYV8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3BhX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IG5vIFBhcsOhIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9wYV9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBQYXLDoSBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgoKYGBgCgpFc3RhZG8gZG8gUGFyYcOtYmEKCmBgYHtyfQogIAoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkYSBQYXJhw61iYSBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfcGJfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIlBCIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0ID0gIiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3BiXzIwMjAgPC0gY292aWRfcGJfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9wYl9yZXN1bW8gPC0gY292aWRfcGJfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9wYl9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBuYSBQYXJhw61iYSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcGJfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbmEgUGFyYcOtYmEgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gUGVybmFtYnVjbwoKCmBgYHtyfQojIFBlcm5hbWJ1Y28KIyBDYXJyZWd1ZSBhcyBiaWJsaW90ZWNhcyBuZWNlc3PDoXJpYXMKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZGUgUGVybmFtYnVjbyBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfcGVfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIlBFIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9wZV8yMDIwIDwtIGNvdmlkX3BlXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfcGVfcmVzdW1vIDwtIGNvdmlkX3BlXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcGVfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gUGVybmFtYnVjbyBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcGVfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gUGVybmFtYnVjbyBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgoKYGBgCgpFc3RhZG8gZG8gUGlhdcOtCgoKYGBge3J9CiNQaWF1w60gCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZG8gUGlhdcOtIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9waV8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiUEkiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3BpXzIwMjAgPC0gY292aWRfcGlfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9waV9yZXN1bW8gPC0gY292aWRfcGlfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9waV9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBQaWF1w60gcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3BpX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IG5vIFBpYXXDrSBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCmBgYAoKRXN0YWRvIGRvIFBhcmFuw6EKCmBgYHtyfQojUGFyYW7DoQojIENhcnJlZ3VlIGFzIGJpYmxpb3RlY2FzIG5lY2Vzc8OhcmlhcwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBQYXJhbsOhIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9wcl8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiUFIiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3ByXzIwMjAgPC0gY292aWRfcHJfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9wcl9yZXN1bW8gPC0gY292aWRfcHJfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9wcl9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBQYXJhbsOhIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9wcl9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBQYXJhbsOhIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIFJpbyBkZSBKYW5laXJvCiAKYGBge3J9CiMgUmlvIERlIEphbmVpcm8gCiMgQ2FycmVndWUgYXMgYmlibGlvdGVjYXMgbmVjZXNzw6FyaWFzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRvIFJpbyBkZSBKYW5laXJvIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9yal8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiUkoiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3JqXzIwMjAgPC0gY292aWRfcmpfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9yal9yZXN1bW8gPC0gY292aWRfcmpfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9yal9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBSaW8gZGUgSmFuZWlybyBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcmpfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gUmlvIGRlIEphbmVpcm8gcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKCmBgYAoKRXN0YWRvIGRvIFJpbyBHcmFuZGUgZG8gTm9ydGUKCmBgYHtyfQojUmlvIEdyYW5kZSBEbyBOb3J0ZQojIENhcnJlZ3VlIGFzIGJpYmxpb3RlY2FzIG5lY2Vzc8OhcmlhcwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBSaW8gR3JhbmRlIGRvIE5vcnRlIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9ybl8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiUk4iKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3JuXzIwMjAgPC0gY292aWRfcm5fMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9ybl9yZXN1bW8gPC0gY292aWRfcm5fMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9ybl9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBSaW8gR3JhbmRlIGRvIE5vcnRlIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9ybl9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBubyBSaW8gR3JhbmRlIGRvIE5vcnRlIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIFJvbmTDtG5pYQoKYGBge3J9CiMgQ2FycmVndWUgYXMgYmlibGlvdGVjYXMgbmVjZXNzw6FyaWFzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIFJvbmTDtG5pYSBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfcm9fMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIlJPIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9yb18yMDIwIDwtIGNvdmlkX3JvXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfcm9fcmVzdW1vIDwtIGNvdmlkX3JvXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcm9fcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gUm9uZMO0bmlhIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9yb19yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBSb25kw7RuaWEgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKCmBgYAoKRXN0YWRvIGRvIFJvcmFpbWEKCgpgYGB7cn0KI1JvcmlhbWEKIyBDYXJyZWd1ZSBhcyBiaWJsaW90ZWNhcyBuZWNlc3PDoXJpYXMKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZGUgUm9yYWltYSBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfcnJfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIlJSIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9ycl8yMDIwIDwtIGNvdmlkX3JyXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfcnJfcmVzdW1vIDwtIGNvdmlkX3JyXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcnJfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gUm9yYWltYSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcnJfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gUm9yYWltYSBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgpgYGAKCkVzdGFkbyBkbyBSaW8gR3JhbmRlIGRvIFN1bAoKYGBge3J9CiNSaW8gR3JhbmRlIERvIFN1bAojIENhcnJlZ3VlIGFzIGJpYmxpb3RlY2FzIG5lY2Vzc8OhcmlhcwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkbyBSaW8gR3JhbmRlIGRvIFN1bCBlIHJlbm9tZWllIGFzIGNvbHVuYXMKY292aWRfcnNfMjAyMCA8LSBjb3ZpZC5lc3RhZG9zICU+JQogIGZpbHRlcihlc3RhZG8gPT0gIlJTIikgJT4lCiAgc2VsZWN0KGRhdGEsIGNhc29zTm92b3MsIG9iaXRvc05vdm9zKSAlPiUKICBtdXRhdGUoZGF0YSA9IGFzLkRhdGUoZGF0YSwgZm9ybWF0PSIlWS0lbS0lZCIpKQoKIyBDcmllIGNvbHVuYXMgcGFyYSBvIGFubyBlIG8gbcOqcwpjb3ZpZF9yc18yMDIwIDwtIGNvdmlkX3JzXzIwMjAgJT4lCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eWVhcihkYXRhKSwKICAgICAgICAgbWVzID0gbHVicmlkYXRlOjptb250aChkYXRhKSkKCiMgQWdydXBlIHBvciBhbm8gZSBtw6pzIGUgY2FsY3VsZSBvcyBjYXNvcyBlIMOzYml0b3Mgbm92b3MKY292aWRfcnNfcmVzdW1vIDwtIGNvdmlkX3JzXzIwMjAgJT4lCiAgZ3JvdXBfYnkoYW5vLCBtZXMpICU+JQogIHN1bW1hcmlzZShjYXNvc05vdm9zID0gc3VtKGNhc29zTm92b3MpLAogICAgICAgICAgICBvYml0b3NOb3ZvcyA9IHN1bShvYml0b3NOb3ZvcyksIC5ncm91cHMgPSAnZHJvcF9sYXN0JykKCiMgRnVuw6fDo28gcGFyYSBjcmlhciBncsOhZmljb3MKY3JpYXJfZ3JhZmljbyA8LSBmdW5jdGlvbihkYXRhLCB5LCB0aXR1bG8sIHlsYWIpIHsKICBnZ3Bsb3QoZGF0YSwgYWVzKHggPSBmYWN0b3IobWVzKSwgeSA9IHt7eX19LCBmaWxsID0gZmFjdG9yKGFubykpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjUpICsKICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgIHggPSAiTcOqcyIsCiAgICAgICAgIHkgPSB5bGFiKSArCiAgICB0aGVtZV9taW5pbWFsKCkKfQoKIyBDcmllIGdyw6FmaWNvcwpncmFmaWNvX2Nhc29zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfcnNfcmVzdW1vLCBjYXNvc05vdm9zLCAiQ2Fzb3MgTm92b3MgZGUgQ09WSUQtMTkgbm8gUmlvIEdyYW5kZSBkbyBTdWwgcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3JzX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IG5vIFJpbyBHcmFuZGUgZG8gU3VsIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIFNhbnRhIENhdGFyaW5hCgpgYGB7cn0KI1NhbnRhIENhdGFyaW5hCiMgQ2FycmVndWUgYXMgYmlibGlvdGVjYXMgbmVjZXNzw6FyaWFzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIFNhbnRhIENhdGFyaW5hIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9zY18yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiU0MiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3NjXzIwMjAgPC0gY292aWRfc2NfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9zY19yZXN1bW8gPC0gY292aWRfc2NfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9zY19yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBTYW50YSBDYXRhcmluYSBwb3IgTcOqcyIsICJDYXNvcyBOb3ZvcyIpCmdyYWZpY29fb2JpdG9zIDwtIGNyaWFyX2dyYWZpY28oY292aWRfc2NfcmVzdW1vLCBvYml0b3NOb3ZvcywgIsOTYml0b3MgTm92b3MgZGUgQ09WSUQtMTkgZW0gU2FudGEgQ2F0YXJpbmEgcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgpFc3RhZG8gZG8gU2VyZ2lwZQoKYGBge3J9CiMgU2VyZ2lwZQojIENhcnJlZ3VlIGFzIGJpYmxpb3RlY2FzIG5lY2Vzc8OhcmlhcwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQoKIyBGaWx0cmUgb3MgZGFkb3MgcGFyYSBvIGVzdGFkbyBkZSBTZXJnaXBlIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF9zZV8yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiU0UiKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3NlXzIwMjAgPC0gY292aWRfc2VfMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF9zZV9yZXN1bW8gPC0gY292aWRfc2VfMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9zZV9yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBTZXJnaXBlIHBvciBNw6pzIiwgIkNhc29zIE5vdm9zIikKZ3JhZmljb19vYml0b3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF9zZV9yZXN1bW8sIG9iaXRvc05vdm9zLCAiw5NiaXRvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBTZXJnaXBlIHBvciBNw6pzIiwgIsOTYml0b3MgTm92b3MiKQoKIyBFeGliYSBhbWJvcyBvcyBncsOhZmljb3MgbGFkbyBhIGxhZG8KZ3JpZC5hcnJhbmdlKGdyYWZpY29fY2Fzb3MsIGdyYWZpY29fb2JpdG9zLCBuY29sID0gMSkKCmBgYAoKRXN0YWRvIGRvIFPDo28gUGF1bG8KCmBgYHtyfQojIFPDo28gUGF1bG8gCiMgQ2FycmVndWUgYXMgYmlibGlvdGVjYXMgbmVjZXNzw6FyaWFzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIEZpbHRyZSBvcyBkYWRvcyBwYXJhIG8gZXN0YWRvIGRlIFPDo28gUGF1bG8gZSByZW5vbWVpZSBhcyBjb2x1bmFzCmNvdmlkX3NwXzIwMjAgPC0gY292aWQuZXN0YWRvcyAlPiUKICBmaWx0ZXIoZXN0YWRvID09ICJTUCIpICU+JQogIHNlbGVjdChkYXRhLCBjYXNvc05vdm9zLCBvYml0b3NOb3ZvcykgJT4lCiAgbXV0YXRlKGRhdGEgPSBhcy5EYXRlKGRhdGEsIGZvcm1hdD0iJVktJW0tJWQiKSkKCiMgQ3JpZSBjb2x1bmFzIHBhcmEgbyBhbm8gZSBvIG3DqnMKY292aWRfc3BfMjAyMCA8LSBjb3ZpZF9zcF8yMDIwICU+JQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnllYXIoZGF0YSksCiAgICAgICAgIG1lcyA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0YSkpCgojIEFncnVwZSBwb3IgYW5vIGUgbcOqcyBlIGNhbGN1bGUgb3MgY2Fzb3MgZSDDs2JpdG9zIG5vdm9zCmNvdmlkX3NwX3Jlc3VtbyA8LSBjb3ZpZF9zcF8yMDIwICU+JQogIGdyb3VwX2J5KGFubywgbWVzKSAlPiUKICBzdW1tYXJpc2UoY2Fzb3NOb3ZvcyA9IHN1bShjYXNvc05vdm9zKSwKICAgICAgICAgICAgb2JpdG9zTm92b3MgPSBzdW0ob2JpdG9zTm92b3MpLCAuZ3JvdXBzID0gJ2Ryb3BfbGFzdCcpCgojIEZ1bsOnw6NvIHBhcmEgY3JpYXIgZ3LDoWZpY29zCmNyaWFyX2dyYWZpY28gPC0gZnVuY3Rpb24oZGF0YSwgeSwgdGl0dWxvLCB5bGFiKSB7CiAgZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKG1lcyksIHkgPSB7e3l9fSwgZmlsbCA9IGZhY3Rvcihhbm8pKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSArCiAgICBsYWJzKHRpdGxlID0gdGl0dWxvLAogICAgICAgICB4ID0gIk3DqnMiLAogICAgICAgICB5ID0geWxhYikgKwogICAgdGhlbWVfbWluaW1hbCgpCn0KCiMgQ3JpZSBncsOhZmljb3MKZ3JhZmljb19jYXNvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3NwX3Jlc3VtbywgY2Fzb3NOb3ZvcywgIkNhc29zIE5vdm9zIGRlIENPVklELTE5IGVtIFPDo28gUGF1bG8gcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3NwX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IGVtIFPDo28gUGF1bG8gcG9yIE3DqnMiLCAiw5NiaXRvcyBOb3ZvcyIpCgojIEV4aWJhIGFtYm9zIG9zIGdyw6FmaWNvcyBsYWRvIGEgbGFkbwpncmlkLmFycmFuZ2UoZ3JhZmljb19jYXNvcywgZ3JhZmljb19vYml0b3MsIG5jb2wgPSAxKQoKYGBgCgoKRXN0YWRvIGRvIFRvY2FudGlucwoKYGBge3J9CiNUb2NhbnRpbnMKIyBDYXJyZWd1ZSBhcyBiaWJsaW90ZWNhcyBuZWNlc3PDoXJpYXMKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKCiMgRmlsdHJlIG9zIGRhZG9zIHBhcmEgbyBlc3RhZG8gZGUgVG9jYW50aW5zIGUgcmVub21laWUgYXMgY29sdW5hcwpjb3ZpZF90b18yMDIwIDwtIGNvdmlkLmVzdGFkb3MgJT4lCiAgZmlsdGVyKGVzdGFkbyA9PSAiVE8iKSAlPiUKICBzZWxlY3QoZGF0YSwgY2Fzb3NOb3Zvcywgb2JpdG9zTm92b3MpICU+JQogIG11dGF0ZShkYXRhID0gYXMuRGF0ZShkYXRhLCBmb3JtYXQ9IiVZLSVtLSVkIikpCgojIENyaWUgY29sdW5hcyBwYXJhIG8gYW5vIGUgbyBtw6pzCmNvdmlkX3RvXzIwMjAgPC0gY292aWRfdG9fMjAyMCAlPiUKICBtdXRhdGUoYW5vID0gbHVicmlkYXRlOjp5ZWFyKGRhdGEpLAogICAgICAgICBtZXMgPSBsdWJyaWRhdGU6Om1vbnRoKGRhdGEpKQoKIyBBZ3J1cGUgcG9yIGFubyBlIG3DqnMgZSBjYWxjdWxlIG9zIGNhc29zIGUgw7NiaXRvcyBub3Zvcwpjb3ZpZF90b19yZXN1bW8gPC0gY292aWRfdG9fMjAyMCAlPiUKICBncm91cF9ieShhbm8sIG1lcykgJT4lCiAgc3VtbWFyaXNlKGNhc29zTm92b3MgPSBzdW0oY2Fzb3NOb3ZvcyksCiAgICAgICAgICAgIG9iaXRvc05vdm9zID0gc3VtKG9iaXRvc05vdm9zKSwgLmdyb3VwcyA9ICdkcm9wX2xhc3QnKQoKIyBGdW7Dp8OjbyBwYXJhIGNyaWFyIGdyw6FmaWNvcwpjcmlhcl9ncmFmaWNvIDwtIGZ1bmN0aW9uKGRhdGEsIHksIHRpdHVsbywgeWxhYikgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihtZXMpLCB5ID0ge3t5fX0sIGZpbGwgPSBmYWN0b3IoYW5vKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogICAgbGFicyh0aXRsZSA9IHRpdHVsbywKICAgICAgICAgeCA9ICJNw6pzIiwKICAgICAgICAgeSA9IHlsYWIpICsKICAgIHRoZW1lX21pbmltYWwoKQp9CgojIENyaWUgZ3LDoWZpY29zCmdyYWZpY29fY2Fzb3MgPC0gY3JpYXJfZ3JhZmljbyhjb3ZpZF90b19yZXN1bW8sIGNhc29zTm92b3MsICJDYXNvcyBOb3ZvcyBkZSBDT1ZJRC0xOSBlbSBUb2NhbnRpbnMgcG9yIE3DqnMiLCAiQ2Fzb3MgTm92b3MiKQpncmFmaWNvX29iaXRvcyA8LSBjcmlhcl9ncmFmaWNvKGNvdmlkX3RvX3Jlc3Vtbywgb2JpdG9zTm92b3MsICLDk2JpdG9zIE5vdm9zIGRlIENPVklELTE5IGVtIFRvY2FudGlucyBwb3IgTcOqcyIsICLDk2JpdG9zIE5vdm9zIikKCiMgRXhpYmEgYW1ib3Mgb3MgZ3LDoWZpY29zIGxhZG8gYSBsYWRvCmdyaWQuYXJyYW5nZShncmFmaWNvX2Nhc29zLCBncmFmaWNvX29iaXRvcywgbmNvbCA9IDEpCgpgYGAKCgo=